package haitao.picker.datepicker;


import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.TextView;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import haitao.library.picker.R;
import haitao.picker.view.WheelView;

/**
 * @Description: DatePicker.java
 * @Author wanghaitao
 * @Date 2019/12/20 15:45
 * @Version V1.0
 */

public class DatePicker extends LinearLayout {

    private WheelView yearPicker;
    private WheelView monthPicker;
    private WheelView dayPicker;
    private WheelView hourPicker;
    private WheelView minutePicker;

    private TextView yearTv;
    private TextView monthTv;
    private TextView dayTv;
    private TextView hourTv;
    private TextView minuteTv;

    private OnDateSelectedListener onDateSelectedListener;

    private int yearIndex = 0;
    private int monthIndex = 0;
    private int dayIndex = 0;
    private int hourIndex = 0;
    private int minuteIndex = 0;
    private Context context;

    private boolean showTime;
    private boolean showHint;
    protected List<String> yearData;
    protected List<String> monthData;
    protected List<String> dayData;
    protected List<String> hourData;
    protected List<String> minuteData;

    private Date startDate;
    private Date endDate;
    private Date defaultSelectDate;

    private String startDateStr = "2015-01-01";
    private String endDateStr = "2016-09-01";

    private int startYear;
    private int startMonth;
    private int startDay;
    private int startHour;
    private int startMinute;

    private int endYear;
    private int endMonth;
    private int endDay;
    private int endHour;
    private int endMinute;

    public DatePicker(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.context = context;
        init();
    }

    public DatePicker(Context context) {
        super(context);
        this.context = context;
        init();
    }

    private void init() {
        LayoutInflater.from(getContext()).inflate(R.layout.time_picker, this);
        yearPicker = findViewById(R.id.year_picker);
        monthPicker = findViewById(R.id.month_picker);
        dayPicker = findViewById(R.id.day_picker);
        hourPicker = findViewById(R.id.hour_picker);
        minutePicker = findViewById(R.id.minute_picker);
        yearTv = findViewById(R.id.year_tv);
        monthTv = findViewById(R.id.month_tv);
        dayTv = findViewById(R.id.day_tv);
        hourTv = findViewById(R.id.hour_tv);
        minuteTv = findViewById(R.id.minute_tv);
        initDate();
        showTime(false);
    }

    public void setDate(String startDateStr, String endDateStr) {
        this.endDateStr = endDateStr;
        this.startDateStr = startDateStr;
        initDate();
    }


    public void setDate(Date startDate, Date endDate) {
        this.startDate = startDate;
        this.endDate = endDate;
        initDate();
    }

    public void setDate(Date startDate, Date endDate, Date defaultSelectDate) {
        this.startDate = startDate;
        this.endDate = endDate;
        this.defaultSelectDate = defaultSelectDate;
        initDate();
    }

    public void showHintText(boolean show) {
        this.showHint = show;
        dayTv.setVisibility(show ? View.VISIBLE : View.GONE);
        yearTv.setVisibility(show ? View.VISIBLE : View.GONE);
        monthTv.setVisibility(show ? View.VISIBLE : View.GONE);

        hourTv.setVisibility(show ? View.VISIBLE : View.GONE);
        minuteTv.setVisibility(show ? View.VISIBLE : View.GONE);
    }

    public void showTime(boolean showTime) {
        this.showTime = showTime;
        hourPicker.setVisibility(showTime ? View.VISIBLE : View.GONE);
        minutePicker.setVisibility(showTime ? View.VISIBLE : View.GONE);
        if (showTime) {
            hourTv.setVisibility(showHint ? View.VISIBLE : View.GONE);
            minuteTv.setVisibility(showHint ? View.VISIBLE : View.GONE);
        } else {
            hourTv.setVisibility(View.GONE);
            minuteTv.setVisibility(View.GONE);
        }

        LayoutParams ll = (LayoutParams) dayTv.getLayoutParams();
        ll.rightMargin = dp2px(context, showTime ? 0 : 6);
    }

    private int dp2px(Context context, float value) {
        float scale = (float) context.getResources().getDisplayMetrics().densityDpi;
        return (int) (value * (scale / 160.0F) + 0.5F);
    }

    private void initDate() {

        if (null == startDate) {
            startDate = stringToDate(startDateStr, "yyyy-MM-dd");
            endDate = stringToDate(endDateStr, "yyyy-MM-dd");
        }

        Calendar cal = Calendar.getInstance();
        cal.setTime(startDate);
        startYear = cal.get(Calendar.YEAR);
        startMonth = cal.get(Calendar.MONTH) + 1;
        startDay = cal.get(Calendar.DAY_OF_MONTH);
        startHour = cal.get(Calendar.HOUR_OF_DAY);
        startMinute = cal.get(Calendar.MINUTE);

        cal.setTime(endDate);

        endYear = cal.get(Calendar.YEAR);
        endMonth = cal.get(Calendar.MONTH) + 1;
        endDay = cal.get(Calendar.DAY_OF_MONTH);
        endHour = cal.get(Calendar.HOUR_OF_DAY);
        endMinute = cal.get(Calendar.MINUTE);

        yearData = new ArrayList();
        monthData = new ArrayList();
        dayData = new ArrayList();
        minuteData = new ArrayList();
        // 计算年份
        for (int i = startYear; i <= endYear; i++) {
            yearData.add(i + "");
        }
        if (defaultSelectDate != null) {
            cal.setTime(defaultSelectDate);
            int year = cal.get(Calendar.YEAR);
            int month = cal.get(Calendar.MONTH) + 1;
            int day = cal.get(Calendar.DAY_OF_MONTH);
            int hour = cal.get(Calendar.HOUR_OF_DAY);
            int minute = cal.get(Calendar.MINUTE);

            int minMonth = 1;
            int maxMonth = 12;
            if (year == startYear) {
                minMonth = startMonth;
            }
            if (year == endYear) {
                maxMonth = endMonth;
            }
            for (int i = minMonth; i <= maxMonth; i++) {
                monthData.add(i + "");
            }

            int minDay = 1;
            int maxDay = days(year, month);

            if (year == startYear && month == startMonth) {
                minDay = startDay;
            }
            if (year == endYear && month == endMonth) {
                maxDay = endDay;
            }
            for (int i = minDay; i <= maxDay; i++) {
                dayData.add(i + "");
            }

            int minHour = 0;
            int maxHour = 23;

            if (year == startYear && month == startMonth && day == startDay) {
                minHour = startHour;
            }
            if (year == endYear && month == endMonth && day == endDay) {
                maxHour = endHour;
            }
            hourData = new ArrayList();
            for (int i = minHour; i <= maxHour; i++) {
                hourData.add(i + "");
            }

            int minMinute = 0;
            int maxMinute = 59;

            if (year == startYear && month == startMonth && day == startDay && hour == startHour) {
                minMinute = startMinute;
            }
            if (year == endYear && month == endMonth && day == endDay && hour == endHour) {
                maxMinute = endMinute;
            }
            for (int i = minMinute; i <= maxMinute; i++) {
                minuteData.add(i + "");
            }
            minuteIndex = minute - minMinute;
            hourIndex = hour - minHour;
            dayIndex = day - minDay;
            monthIndex = month - minMonth;
            yearIndex = year - startYear;
        } else {
            // 计算月份
            int start = startMonth;
            int end = 12;
            if (startYear == endYear) {
                end = endMonth;
            }

            for (int i = start; i <= end; i++) {
                monthData.add(i + "");
            }

            //计算天
            if (startYear == endYear && startMonth == endMonth) {
                for (int i = startDay; i <= endDay; i++) {
                    dayData.add(i + "");
                }
            } else {
                int maxDay = days(startYear, startMonth);
                for (int i = startDay; i <= maxDay; i++) {
                    dayData.add(i + "");
                }
            }

            start = startHour;
            end = 23;
            if (startYear == endYear && startMonth == endMonth && startDay == endDay) {
                end = endHour;
            }
            hourData = new ArrayList();
            for (int i = start; i <= end; i++) {
                hourData.add(i + "");
            }

            start = startMinute;
            end = 59;
            if (startYear == endYear && startMonth == endMonth && startDay == endDay && startHour == endHour) {
                end = endMinute;
            }

            for (int i = start; i <= end; i++) {
                minuteData.add(i + "");
            }

        }

        yearPicker.setData(yearData);
        yearPicker.setSelectedItemPosition(yearIndex);
        monthPicker.setData(monthData);
        monthPicker.setSelectedItemPosition(monthIndex);
        dayPicker.setData(dayData);
        dayPicker.setSelectedItemPosition(dayIndex);
        hourPicker.setData(hourData);
        hourPicker.setSelectedItemPosition(hourIndex);
        minutePicker.setData(minuteData);
        minutePicker.setSelectedItemPosition(minuteIndex);

        yearPicker.setOnItemSelectedListener(new WheelView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(WheelView wheelView, Object data, int position) {
                yearIndex = position;
                countMonth();
                countDay();
                if (showTime) {
                    countHour();
                    countMinute();
                }
                notifySelect();
            }
        });
        monthPicker.setOnItemSelectedListener(new WheelView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(WheelView wheelView, Object data, int position) {
                monthIndex = position;
                countDay();
                if (showTime) {
                    countHour();
                    countMinute();
                }
                notifySelect();
            }
        });
        dayPicker.setOnItemSelectedListener(new WheelView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(WheelView wheelView, Object data, int position) {
                dayIndex = position;
                if (showTime) {
                    countHour();
                    countMinute();
                }

                notifySelect();
            }
        });
        hourPicker.setOnItemSelectedListener(new WheelView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(WheelView wheelView, Object data, int position) {
                hourIndex = position;
                countMinute();
                notifySelect();
            }
        });
        minutePicker.setOnItemSelectedListener(new WheelView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(WheelView wheelView, Object data, int position) {
                minuteIndex = position;
                countMinute();
                notifySelect();
            }
        });


    }

    private void notifySelect() {
        if (null != onDateSelectedListener) {
            Date date = getSelectDate();
            String dateStr = new SimpleDateFormat(showTime ? "yyyy-MM-dd HH:mm" : "yyyy-MM-dd").format(date);
            onDateSelectedListener.onDateSelected(date, dateStr);
        }
    }

    private void countMonth() {
        //  月份的计算
        int minMonth = 1;
        int maxMonth = 12;
        int lastNum = Integer.parseInt(monthData.get(monthIndex));

        if (yearData.get(yearIndex).equals(startYear + "")) {
            minMonth = startMonth;
        }
        if (yearData.get(yearIndex).equals(endYear + "")) {
            maxMonth = endMonth;
        }

        monthData = new ArrayList();
        for (int i = minMonth; i <= maxMonth; i++) {
            monthData.add(i + "");
        }
        // 判断日期是否超过

        if (lastNum <= minMonth) {
            monthIndex = 0;
        } else if (lastNum >= maxMonth) {
            monthIndex = monthData.size() - 1;
        } else {
            monthIndex = lastNum - minMonth;
        }
        monthPicker.setData(monthData);
        monthPicker.setSelectedItemPosition(monthIndex);
    }

    private void countDay() {
        int minDay = 1;
        int maxDay = days(Integer.parseInt(yearData.get(yearIndex)), Integer.parseInt(monthData.get(monthIndex)));
        int lastNum = Integer.parseInt(dayData.get(dayIndex));
        // 天的计算

        if (yearData.get(yearIndex).equals(startYear + "") && monthData.get(monthIndex).equals(startMonth + "")) {
            minDay = startDay;
        }
        if (yearData.get(yearIndex).equals(endYear + "") && monthData.get(monthIndex).equals(endMonth + "")) {
            maxDay = endDay;
        }
        dayData = new ArrayList<>();
        for (int i = minDay; i <= maxDay; i++) {
            dayData.add(i + "");
        }

        if (lastNum <= minDay) {
            dayIndex = 0;
        } else if (lastNum >= maxDay) {
            dayIndex = dayData.size() - 1;
        } else {
            dayIndex = lastNum - minDay;
        }
        dayPicker.setData(dayData);
        dayPicker.setSelectedItemPosition(dayIndex);
    }

    private void countHour() {
        // 小时的计算
        int minHour = 0;
        int maxHour = 23;
        int lastNum = Integer.parseInt(hourData.get(hourIndex));

        if (yearData.get(yearIndex).equals(startYear + "") && monthData.get(monthIndex).equals(startMonth + "") && dayData.get(dayIndex).equals(startDay + "")) {
            minHour = startHour;
        }
        if (yearData.get(yearIndex).equals(endYear + "") && monthData.get(monthIndex).equals(endMonth + "") && dayData.get(dayIndex).equals(endDay + "")) {
            maxHour = endHour;
        }
        hourData = new ArrayList<>();
        for (int i = minHour; i <= maxHour; i++) {
            hourData.add(i + "");
        }

        if (lastNum <= minHour) {
            hourIndex = 0;
        } else if (lastNum >= maxHour) {
            hourIndex = hourData.size() - 1;
        } else {
            hourIndex = lastNum - minHour;
        }
        hourPicker.setData(hourData);
        hourPicker.setSelectedItemPosition(hourIndex);
    }

    private void countMinute() {
        // 分钟的计算
        int minMinute = 0;
        int maxMinute = 59;
        int lastNum = Integer.parseInt(minuteData.get(minuteIndex));

        if (yearData.get(yearIndex).equals(startYear + "") && monthData.get(monthIndex).equals(startMonth + "") && dayData.get(dayIndex).equals(startDay + "") && hourData.get(hourIndex).equals(startHour + "")) {
            minMinute = startMinute;
        }
        if (yearData.get(yearIndex).equals(endYear + "") && monthData.get(monthIndex).equals(endMonth + "") && dayData.get(dayIndex).equals(endDay + "") && hourData.get(hourIndex).equals(endHour + "")) {
            maxMinute = endMinute;
        }
        minuteData = new ArrayList<>();
        for (int i = minMinute; i <= maxMinute; i++) {
            minuteData.add(i + "");
        }
        if (lastNum <= minMinute) {
            minuteIndex = 0;
        } else if (lastNum >= maxMinute) {
            minuteIndex = minuteData.size() - 1;
        } else {
            minuteIndex = lastNum - minMinute;
        }
        minutePicker.setData(minuteData);
        minutePicker.setSelectedItemPosition(minuteIndex);
    }

    public int days(int year, int month) {
        int days = 0;
        if (month != 2) {
            switch (month) {
                case 1:
                case 3:
                case 5:
                case 7:
                case 8:
                case 10:
                case 12:
                    days = 31;
                    break;
                case 4:
                case 6:
                case 9:
                case 11:
                    days = 30;

            }
        } else {
            //闰年
            if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0)
                days = 29;
            else
                days = 28;

        }
        return days;

    }

    /**
     * string类型转换为date类型
     *
     * @param strTime
     * @return
     */
    public Date stringToDate(String strTime, String format) {
        SimpleDateFormat formatter = new SimpleDateFormat(format);
        Date date = null;
        try {
            date = formatter.parse(strTime);
        } catch (ParseException e) {
            // TODO Auto-generated catch block;
            Log.e("date error", e.toString());
        }
        return date;
    }

    public Date getSelectDate() {
        if (showTime) {
            return stringToDate(yearData.get(yearIndex) + "-" + monthData.get(monthIndex) + "-" + dayData.get(dayIndex) + " " + hourData.get(hourIndex) + ":" + minuteData.get(minuteIndex), showTime ? "yyyy-MM-dd HH:mm" : "yyyy-MM-dd");
        }
        return stringToDate(yearData.get(yearIndex) + "-" + monthData.get(monthIndex) + "-" + dayData.get(dayIndex), showTime ? "yyyy-MM-dd HH:mm" : "yyyy-MM-dd");
    }

    public String getSelectDateStr() {
        return new SimpleDateFormat(showTime ? "yyyy-MM-dd HH:mm" : "yyyy-MM-dd").format(getSelectDate());
    }

    public void setOnDateSelectedListener(OnDateSelectedListener onDateSelectedListener) {
        this.onDateSelectedListener = onDateSelectedListener;
    }


    public interface OnDateSelectedListener {

        void onDateSelected(Date selectDate, String selectDateStr);
    }
}